package com.star.percalservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.star.percalservice.mapper.*;
import com.star.percalservice.model.entity.*;
import com.star.percalservice.service.ScoreRuleService;
import com.star.percalservice.utils.R;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author star
 * @version 1.0
 * @Description:
 * @DateTime 2025/4/12 6:25
 */

@Service
public class ScoreRuleServiceImpl implements ScoreRuleService {

    @Autowired
    private ScoreRuleMapper scoreRuleMapper;
    @Autowired
    private TeacherMapper teacherMapper;
    @Autowired
    private ResearchProjectMapper researchProjectMapper;
    @Autowired
    private PaperMapper paperMapper;
    @Autowired
    private PatentMapper patentMapper;
    @Autowired
    private AwardMapper awardMapper;

    // 规则缓存 key: rule_code, value: score
    private Map<String, Double> ruleCache = new HashMap<>();

    @PostConstruct // 服务启动时加载规则
    public void initRuleCache() {
        List<ScoreRule> rules = scoreRuleMapper.selectList(null);
        rules.forEach(rule -> ruleCache.put(rule.getType(), Double.valueOf(rule.getScore())));
    }

    @Override
    public Double calculateScore(Integer teacherId) {
        // 验证教师存在
        Teacher teacher = teacherMapper.selectById(teacherId);
        if (teacher == null) {
            throw new RuntimeException("教师不存在");
        }

        double totalScore = 0.0;

        // 科研项目计分
        totalScore += calculateProjectsScore(teacherId);

        // 论文计分
        totalScore += calculatePapersScore(teacherId);

        // 专利计分
        totalScore += calculatePatentsScore(teacherId);

        // 奖项计分
        totalScore += calculateAwardsScore(teacherId);

        return totalScore;
    }

    @Override
    public R list() {
        return R.ok("查询成功", scoreRuleMapper.selectList(null));
    }

    @Override
    public R add(ScoreRule scoreRule) {
        return scoreRuleMapper.insert(scoreRule) > 0 ? R.ok("添加成功") : R.error("添加失败");
    }

    @Override
    public R update(ScoreRule scoreRule) {
        return scoreRuleMapper.updateById(scoreRule) > 0 ? R.ok("修改成功") : R.error("修改失败");
    }

    @Override
    public R delete(Integer id) {
        return scoreRuleMapper.deleteById(id) > 0 ? R.ok("删除成功") : R.error("删除失败");
    }

    private double calculateProjectsScore(Integer teacherId) {
        double score = 0;

        // 实时查询数据库获取最新规则分数
        ScoreRule nationalRule = scoreRuleMapper.selectOne(new QueryWrapper<ScoreRule>()
                .eq("type", "project_national"));
        ScoreRule provincialRule = scoreRuleMapper.selectOne(new QueryWrapper<ScoreRule>()
                .eq("type", "project_provincial"));
        ScoreRule horizontalRule = scoreRuleMapper.selectOne(new QueryWrapper<ScoreRule>()
                .eq("type", "project_horizontal"));

        // 获取分数值（处理可能为null的情况）
        double nationalScore = nationalRule != null ? nationalRule.getScore() : 0;
        double provincialScore = provincialRule != null ? provincialRule.getScore() : 0;
        double horizontalScore = horizontalRule != null ? horizontalRule.getScore() : 0;

        // 国家级项目数量
        int nationalCount = Math.toIntExact(researchProjectMapper.selectCount(new QueryWrapper<ResearchProject>()
                .eq("teacher_id", teacherId)
                .eq("type", "national")
                .eq("status", "approved")));

        // 省级项目数量
        int provincialCount = Math.toIntExact(researchProjectMapper.selectCount(new QueryWrapper<ResearchProject>()
                .eq("teacher_id", teacherId)
                .eq("type", "provincial")
                .eq("status", "approved")));

        // 横向项目数量
        int horizontalCount = Math.toIntExact(researchProjectMapper.selectCount(new QueryWrapper<ResearchProject>()
                .eq("teacher_id", teacherId)
                .eq("type", "horizontal")
                .eq("status", "approved")));

        score += nationalCount * nationalScore;
        score += provincialCount * provincialScore;
        score += horizontalCount * horizontalScore;

        return score;
    }


    private double calculatePapersScore(Integer teacherId) {
        // 实时查询论文分数规则
        ScoreRule journalRule = scoreRuleMapper.selectOne(new QueryWrapper<ScoreRule>()
                .eq("type", "paper_journal"));
        double journalScore = journalRule != null ? journalRule.getScore() : 0;

        int journalCount = Math.toIntExact(paperMapper.selectCount(new QueryWrapper<Paper>()
                .eq("teacher_id", teacherId)
                .eq("status", "approved")));

        return journalCount * journalScore;
    }

    private double calculatePatentsScore(Integer teacherId) {
        double score = 0;

        // 实时查询专利分数规则
        ScoreRule inventionRule = scoreRuleMapper.selectOne(new QueryWrapper<ScoreRule>()
                .eq("type", "patent_invention"));
        ScoreRule utilityModelRule = scoreRuleMapper.selectOne(new QueryWrapper<ScoreRule>()
                .eq("type", "patent_utility_model"));

        double inventionScore = inventionRule != null ? inventionRule.getScore() : 0;
        double utilityModelScore = utilityModelRule != null ? utilityModelRule.getScore() : 0;

        int inventionCount = Math.toIntExact(patentMapper.selectCount(new QueryWrapper<Patent>()
                .eq("teacher_id", teacherId)
                .eq("type", "invention")
                .eq("status", "approved")));

        int utilityModelCount = Math.toIntExact(patentMapper.selectCount(new QueryWrapper<Patent>()
                .eq("teacher_id", teacherId)
                .eq("type", "utility_model")
                .eq("status", "approved")));

        score += inventionCount * inventionScore;
        score += utilityModelCount * utilityModelScore;

        return score;
    }

    private double calculateAwardsScore(Integer teacherId) {
        double score = 0;

        // 实时查询奖项分数规则
        ScoreRule nationalAwardRule = scoreRuleMapper.selectOne(new QueryWrapper<ScoreRule>()
                .eq("type", "award_national"));
        ScoreRule provincialAwardRule = scoreRuleMapper.selectOne(new QueryWrapper<ScoreRule>()
                .eq("type", "award_provincial"));

        double nationalAwardScore = nationalAwardRule != null ? nationalAwardRule.getScore() : 0;
        double provincialAwardScore = provincialAwardRule != null ? provincialAwardRule.getScore() : 0;

        int nationalCount = Math.toIntExact(awardMapper.selectCount(new QueryWrapper<Award>()
                .eq("teacher_id", teacherId)
                .eq("level", "national")
                .eq("status", "approved")));

        int provincialCount = Math.toIntExact(awardMapper.selectCount(new QueryWrapper<Award>()
                .eq("teacher_id", teacherId)
                .eq("level", "provincial")
                .eq("status", "approved")));

        score += nationalCount * nationalAwardScore;
        score += provincialCount * provincialAwardScore;

        return score;
    }

}

